%%%---------------------------------------------------
%%% CCTRANS: preprocessor for Object Oriented Erlang
%%% Written by Gábor Fehér, 2008 at BUTE
%%%---------------------------------------------------
%%% cctests - guard manipulation support in Erlang Abstract Syntax Trees (ASTs)
%%%
%%% Compiles and runs the prepared test modules in cctests/
%%% directory.
-module(master).
-export([dotest/0, dotest_sh/0]). 
-define(MODS,["pattern1", "expr1", "pattern2", "pattern3", "list_pattern", "embedded_pattern",
	      "device", "monitor", "printer", "device_main", "recursive_expr", 
          "vmt1", "vmt2", "clause_boundvars", "record_tests", "rec_in_pattern",
          "multi_guards", "classupdate", "recursive_update", "classupdate_side_effect", "remote_ifc",
          "equality_pattern", "class_imports", "fun_shadow"]).

-include_lib("ect/config.hrl").
-define(COMPILER_OPTIONS,[force_boundvar_checks, report, {i, "../.."}|?ECT_COMMON_OPTIONS]).

%% Compiles a module, either in verbose, or non-verbose mode.
%% Parameters:
%%     Module:  the module name to compile (string)
%%     File:    the file name with path, but without the .erl extension (string)
%%              note that this must be consistent with Module
%%     CCTrans: a compiled erlang module, which is responsible for the 
%%              client part of the oo transformation
%%     Mode:    output message verbosity: verbose or silent
%% Returns: ok on success, error on failure
%% Side-effects: prints error messages, depending on the value of Mode
compile_module(Module, File, CCTrans, silent) ->
    Res0 = compile:file(File, [{cctrans, CCTrans}|?COMPILER_OPTIONS]),
    case Res0 of
	{ok, _} -> c:l(Module), ok;
	_ -> error
    end.

%% Compiles and runs a module.
%% Parameters:
%%     M:       Module name (string)
%%     CCTrans: module responsible for the client part of the oo transformation
%%     Mode:    silent or verbose
compile_module(M, CCTrans, Mode) ->
    Module = list_to_atom(M),
    case Mode of 
	verbose -> io:format("~n~p:~n", [list_to_atom(Module)]);
	_ -> io:format("COMPILE ~p:~n", [Module])
    end,
    File = M++".erl",
    X = compile_module(Module, File, CCTrans, Mode),
    case X of
	ok ->
        io:format("ok~n", []);
	_ ->
	    throw({ecterror, "ABORT: compile failed"})
    end.

%% Runs all the tests in cctests/ direcotory, and prints the results.
%% Parameters:
%%     CCTrans: the module to do the client part of the oo transformation
%%              currently cctrans or cctrans2
%%     Mode:    Style of output messages: verbose or silent
%%
% dotest(CCTrans, Mode) when Mode =:= silent orelse Mode =:= verbose ->
%     lists:map(fun(F) -> testmodule(F, CCTrans, Mode) end, ?MODS),
%     ok.

format_module(M) when length(M) >= 25 ->
    M;
format_module(M) ->
    format_module(M++".").

testmodule(M) ->
    Module = list_to_atom(M),
    io:format("TEST "++format_module(M)++": ", []),
    Res = Module:dotest(),
    if (Res =:= pass) ->
        io:format("PASSED: result=~p~n", [Res]);
    true ->
        io:format("FAILED: result=~p~n", [Res])
    end.

dotest() ->
    try
        lists:map(fun(F) -> compile_module(F, cctrans, silent) end, ?MODS),
        lists:map(fun(F) -> testmodule(F) end, ?MODS),
        ok
    catch
        throw:{ecterror, X} ->
            io:format(X, []),
            error
    end.

dotest_sh() ->
    case dotest() of
    ok -> erlang:halt();
    error -> erlang:halt(1)
    end.